package top.ochiamalu.aioj.disruptor;

import com.lmax.disruptor.RingBuffer;
import org.springframework.stereotype.Component;
import top.ochiamalu.aioj.domain.dto.judge.JudgeDTO;

/**
 * 判题事件生产者
 *
 * @author ochiamalu
 * @date 2025/01/23
 */
@Component
public class JudgeEventProducer {

    private final RingBuffer<JudgeEvent> ringBuffer;

    /**
     * 判题事件生产者初始化构造函数
     *
     * @param ringBuffer 环形缓冲器
     */
    public JudgeEventProducer(RingBuffer<JudgeEvent> ringBuffer) {
        this.ringBuffer = ringBuffer;
    }

    /**
     * 发布事件
     *
     * @param judgeDTO 执行代码dto
     */
    public void publishEvent(JudgeDTO judgeDTO) {
        long sequence = ringBuffer.next();
        try {
            JudgeEvent event = ringBuffer.get(sequence);
            event.setJudgeDTO(judgeDTO);
        } finally {
            ringBuffer.publish(sequence);
        }
    }

    /**
     * 获取等待判题的数量
     * 通过计算RingBuffer中未消费的事件数量来得到等待判题的数量
     *
     * @return 等待判题的数量
     */
    public int getWaitingCount() {
        long cursor = ringBuffer.getCursor();
        long consumed = ringBuffer.getMinimumGatingSequence();
        return (int) (cursor - consumed);
    }
}
